#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cassert>
namespace ljt

{

    template<class T>

    class vector
    {
    public:

        // Vector�ĵ�������һ��ԭ��ָ��

        typedef T* iterator;

        typedef const T* const_iterator;

        iterator begin()
        {
            return _start;
        }

        iterator end()
        {
            return _finish;
        }

        const_iterator cbegin()
        {
            return _start;
        }

        const_iterator cend() const
        {
            return _finish;
        }



        // construct and destroy

        vector()
        {

        }

        vector(int n, const T& value = T())
        {
            reserve(n);
            for (iterator t = _start; t != _finish; t++)
                *t = value;
        }

        template<class InputIterator>

        vector(InputIterator first, InputIterator last)
        {
            for (auto p = first; p != last; p++)
                push_back(*p);
        }

        vector(const vector<T>& v)
        {
            *this = v;
        }

        vector<T>& operator= (vector<T> v)
        {
            delete[] _start;
            _start = new T[v.size()];
            _finish = _start + v.size();
            _endOfStorage = _finish;
            for (int i = 0; i < v.size(); i++)
                _start[i] = v[i];
            
            return *this;
        }

        ~vector()
        {
            delete[] _start;
            _start = nullptr;
            _finish = nullptr;
            _endOfStorage = nullptr;
        }

        // capacity

        size_t size() const
        {
            return _finish - _start;
        }

        size_t capacity() const
        {
            return _endOfStorage - _start;
        }

        void reserve(size_t n)
        {
            if (n > capacity())
            {
                int sz = size();
                T* tmp = new T[n];
                if (_start)
                {
                    for (int i = 0; i < size(); i++)
                        tmp[i] = _start[i];
                    delete[] _start;
                }
                _start = tmp;
                _finish = _start + sz;
                _endOfStorage = _start + n;
            }

        }

        void resize(size_t n, const T& value = T())
        {
            if (n > capacity())
            {
                reserve(n);
                for (int i = size(); i < n; i++)
                    _start[i] = value;
                _finish = _start + n;
                _endOfStorage = _finish;
            }
            else if (n > size() && n < capacity())
            {
                for (int i = size(); i < n; i++)
                    _start[i] = value;
                _finish = _start + n;
            }
        }



            ///////////////access///////////////////////////////

        T& operator[](size_t pos)
        {
            return _start[pos];
        }

        const T& operator[](size_t pos)const
        {
            return _start[pos];
        }



            ///////////////modify/////////////////////////////

        void push_back(const T& x)
        {
            /*if (size() == capacity())
            {
                reserve(size() == 0 ? 4 : 2 * capacity());
                *_finish = x;
                _finish++;
            }
            else
            {
                _start[size()] = x;
                _finish++;
            }*/
            insert(_finish, x);
        }

        void pop_back()
        {
            if (_start == _finish)
                return;
            _finish--;
        }

        void swap(vector<T>& v)
        {
            vector<T> t = v;
            v = *this;
            *this = t;
        }

        iterator insert(iterator pos, const T& x)
        {
            assert(pos <= _finish);
            assert(pos >= _start);
            if (_finish == _endOfStorage)
            {
                int len = pos - _start;
                reserve(capacity() == 0 ? 4 : 2 * capacity());
                pos = _start + len;
            }
            iterator end = _finish - 1;
            while (end >= pos)
            {
                *(end + 1) = *end;
                end--;
            }
            _finish ++;
            *pos = x;
            return pos;
        }

        iterator erase(iterator pos)
        {
            assert(pos <= _finish);
            assert(pos >= _start);
            iterator t = pos;
            while (t + 1 < _finish)
            {
                *t = *(t + 1);
            }
            return pos;
        }

    private:

        iterator _start = nullptr; // ָ�����ݿ�Ŀ�ʼ

        iterator _finish = nullptr; // ָ����Ч���ݵ�β

        iterator _endOfStorage = nullptr; // ָ��洢������β
    };
}